import grpc
import os
import sys

BASE_DIR = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
sys.path.insert(0, BASE_DIR)

from user_srv.proto import user_pb2_grpc
from user_srv.handler.user import UserServicer
from concurrent import futures
import logging
from loguru import logger
import argparse

from common.grpc_health.v1 import health, health_pb2_grpc
from common.register import myconsul
import socket
import signal
from functools import partial
from user_srv.settings import settings


def get_free_tcp_port():
    tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp.bind(("", 0))
    _, port = tcp.getsockname()
    tcp.close()
    return port


def on_exit(signo, frame, service_id):
    register = myconsul.ConsulRegister(settings.CONSUL_HOST, settings.CONSUL_PORT)
    logger.info(f"注销{service_id}服务")
    register.deregister(service_id=service_id)
    logger.info("注销成功")
    sys.exit(0)


def server():
    parser = argparse.ArgumentParser()
    parser.add_argument("--ip",
                        nargs="?",
                        type=str,
                        default="192.168.178.1",
                        help="绑定ip"
                        )
    parser.add_argument("--port",
                        nargs="?",
                        type=int,
                        default=0,
                        help="绑定端口"
                        )
    args = parser.parse_args()

    if args.port == 0:
        port = get_free_tcp_port()
    else:
        port = args.port

    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    user_pb2_grpc.add_UserServicer_to_server(UserServicer(), server)

    import uuid
    service_id = str(uuid.uuid1())
    ##注册健康检查
    health_pb2_grpc.add_HealthServicer_to_server(health.HealthServicer(), server)

    # server.add_insecure_port("192.168.178.1:50051")
    server.add_insecure_port(f'{args.ip}:{port}')
    logger.info(f"服务运行 ：{args.ip}:{port}")
    signal.signal(signal.SIGINT, partial(on_exit, service_id=service_id))
    signal.signal(signal.SIGTERM, partial(on_exit, service_id=service_id))

    server.start()

    logger.info("服务注册开始")
    register = myconsul.ConsulRegister(host=settings.CONSUL_HOST, port=settings.CONSUL_PORT)
    if not register.register(name=settings.SERVICE_NAME, id=service_id, address=args.ip, port=port,
                             tags=settings.SERVICE_TAGS, check=None):
        logger.info("服务注册失败")
        sys.exit(0)
    logger.info("服务注册成功")
    server.wait_for_termination()


if __name__ == '__main__':
    logging.basicConfig()
    settings.client.add_config_watcher(settings.NACOS["DataId"],settings.NACOS["Group"],settings.update_cfg)
    server()
